package com.cloud.drore.eboss.sso.service.impl;

import com.cloud.drore.eboss.sso.base.Constants;
import com.cloud.drore.eboss.sso.base.ResponseJson;
import com.cloud.drore.eboss.sso.base.ResultMessage;
import com.cloud.drore.eboss.sso.base.page.Pagination;
import com.cloud.drore.eboss.sso.base.page.PaginationResult;
import com.cloud.drore.eboss.sso.base.page.SpecificationUtil;
import com.cloud.drore.eboss.sso.dao.ShiroUserDao;
import com.cloud.drore.eboss.sso.entity.EbossRoleRightRelation;
import com.cloud.drore.eboss.sso.entity.Function;
import com.cloud.drore.eboss.sso.entity.ShiroRole;
import com.cloud.drore.eboss.sso.entity.ShiroUser;
import com.cloud.drore.eboss.sso.po.UserAndFunction;
import com.cloud.drore.eboss.sso.service.FunctionService;
import com.cloud.drore.eboss.sso.service.RoleRightService;
import com.cloud.drore.eboss.sso.service.ShiroRoleService;
import com.cloud.drore.eboss.sso.service.ShiroUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ShiroUserServiceImpl extends EntityServiceImpl<ShiroUser, Long, ShiroUserDao> implements ShiroUserService {

	@Autowired
	private FunctionService functionService;

	@Autowired
	private RoleRightService roleRightService;

	@Autowired
	private ShiroUserDao shiroUserDao;


	/**
	 * 管理员修改用户基本信息
	 */
	@Override
	public void editUser(ShiroUser shiroUser){
    	ShiroUser shiroUserTemp = this.findByUsernameForUpdate(shiroUser.getUsername());
		shiroUserTemp.setShowImge(shiroUser.getShowImge());
		shiroUserTemp.setName(shiroUser.getName());
		shiroUserTemp.setJob(shiroUser.getJob());
		shiroUserTemp.setPhone(shiroUser.getPhone());
		shiroUserTemp.setEmail(shiroUser.getEmail());
		this.save(shiroUserTemp);
	  }
	
	/**
	 * 管理员添加用户
	 */
	@Transactional(rollbackFor=Exception.class)
	@Override
	public ResultMessage addUser(ShiroUser shiroUser){

		ShiroUser shiroUserTemp = this.findByUsername(shiroUser.getUsername());
		 if(shiroUserTemp!=null){
			 return ResultMessage.error(8300,"用户已经存在");
		}

		String password = new Md5Hash(Constants.initPassword, "www",1024).toBase64();

		shiroUser.setPassword(password);
		shiroUser.setStatus(Constants.userStatus_1);
		shiroUser.setCreatedDate(new Date());

		this.save(shiroUser);

        return ResultMessage.success(shiroUser.getId());
			
	  }

	@Transactional(rollbackFor=Exception.class)
	@Override
	public ResultMessage addUserAndFunction(ShiroUser shiroUser, List<EbossRoleRightRelation> roleRightRelations){

		String password = new Md5Hash(Constants.initPassword, Constants.md5_pre,1024).toBase64();

		shiroUser.setPassword(password);
		shiroUser.setStatus(Constants.userStatus_1);
		shiroUser.setCreatedDate(new Date());

		this.save(shiroUser);

		roleRightRelations.stream().forEach(roleRightRelation-> roleRightRelation.setRoleId(shiroUser.getId()));

		roleRightService.save(roleRightRelations);

		return ResultMessage.Builder.builder().withId(shiroUser.getId()+"").build();

	}
	
	 
	@Transactional(rollbackFor=Exception.class)
	@Override
	public Boolean checkNameOrEmallExist(ShiroUser shiroUser){
		
		log.info(shiroUser.toString());
		try {
			ShiroUser shiroUserTemp = this.findByUsername(shiroUser.getUsername());

			ShiroUser shiroUserByEmail = shiroUserDao.findFirstByEmail(shiroUser.getEmail());

			if(shiroUserTemp!=null || shiroUserByEmail!=null){
				return false;
			}

		} catch (Exception e) {
			e.printStackTrace();
			return true;
		}

		return true;
	}

	@Override
	public void updateUser(String password) {
		this.entityDao.updateUser(password);
	}

	@Override
	public UserAndFunction getUserFunction(Long id) {
		UserAndFunction userAndFunction = new UserAndFunction();
		userAndFunction.setShiroUser(this.get(id));
		userAndFunction.setEbossRoleRightRelation(roleRightService.findByRoleId(id));
		return userAndFunction;
	}

	@Override
	public void resetPassword(Long id) {
		ShiroUser shiroUser = this.entityDao.findOne(id);
		String password = new Md5Hash(Constants.initPassword, Constants.md5_pre,1024).toBase64();
		shiroUser.setPassword(password);
		this.entityDao.save(shiroUser);
	}

	@Override
	public void disableUser(Long id, int status) {
		ShiroUser shiroUser = this.entityDao.findOne(id);
		if(status == Constants.userStatus_2)
			shiroUser.setStatus(Constants.userStatus_2);
		else if(status == Constants.userStatus_1)
			shiroUser.setStatus(Constants.userStatus_1);
		this.entityDao.save(shiroUser);
	}

	@Override
	public ShiroUser getUserByTypeId(Long typeid) {
		return this.entityDao.findFirstByTypeIdAndIsAdmin(typeid, 1);
	}


	/**
	 * 删除
	 */
	@Override
	@Transactional(rollbackFor=Exception.class)
	public ResponseJson del( String ids)  throws Exception{
		ResponseJson responseJson = new ResponseJson();

		ShiroUser user;
		String idsArr[] = ids.split(",");

		for (int i = 0; i < idsArr.length; i++) {

			user = entityDao.findByUsername(idsArr[i]);
			if(user.getUsername().equals("admin")){
				 responseJson.setMsg("admin");
				 throw new Exception("admin");
			}

			entityDao.delete(user);
		}

		responseJson.setMsg("success");
		return responseJson;
	}

//	  public ResponseJson editUserRole(String username,String roles){
//		  ResponseJson responseJson= new ResponseJson();
//		  ShiroUser shiroUserTemp = this.findByUsernameForUpdate(username);
//		  String rolesArr[] = roles.split(",");
//		  List<ShiroRole> roleList = new ArrayList<ShiroRole>();
//		  for(int i=0;i<rolesArr.length;i++){
//			  ShiroRole  shiroRoleTemp =  shiroRoleService.findByRoleName(rolesArr[i]);
//				roleList.add(shiroRoleTemp);
//		  }
//		shiroUserTemp.setRoleList(roleList);
//		this.save(shiroUserTemp);
//		responseJson.setMsg("success");
//		responseJson.setSuccess(true);
//
//		return responseJson;
//	  }
	 
	@Override
	public ShiroUser findByUsernameForUpdate(String username){
		return entityDao.findByUsernameForUpdate(username);
	 }
	
	@Override
	public ShiroUser findByUsername(String username) {
		ShiroUser shiroUser = entityDao.findByUsernameForUpdate(username);
		if(shiroUser !=null){
			if(shiroUser.getIsAdmin()==1){
				List<Function> functions = functionService.findByTenantId(shiroUser.getType());
				List<EbossRoleRightRelation> rightList = functions.stream().map(function -> {
					EbossRoleRightRelation relation = new EbossRoleRightRelation();
					relation.setRoleId(shiroUser.getId());
					relation.setRightId(function.getId());
					relation.setRightCode(function.getRightCode());
					return relation;
				}).collect(Collectors.toList());
				shiroUser.setRightList(rightList);
			}else
				shiroUser.setRightList(roleRightService.findByRoleId(shiroUser.getId()));
		}
		return shiroUser;
	}

	@Override
	public ShiroUser findByUsernameAndPassword(String username, String password) {
		return entityDao.findByUsernameAndPassword(username, password);
	}

//	@Transactional(rollbackFor=Exception.class)
//	@Override
//	public ResponseJson audit(String userNameStr,int status)  throws Exception{
//
//		ResponseJson responseJson = new ResponseJson();
//
//		responseJson.setMsg("success");
//		 String userNameArray[]=userNameStr.split(",");
//		 int length = userNameArray.length;
//		 log.info("length===="+length);
//
//			for(int i =0;i<length;i++){
//				String username = userNameArray[i];
//				 log.info("username===="+username);
//				 log.info("status===="+status);
//				ShiroUser  shiroUser = entityDao.findByUsernameForUpdate(username);
//
//				if(shiroUser.getRoleList()==null||shiroUser.getRoleList().size()==0){//审核之前必须先给用户赋角色
//					throw new Exception("roleNotExist");
//				}else{
//
//					shiroUser.setStatus(status);
//					entityDao.save(shiroUser);
//					responseJson.setMsg("success");
//				}
//
//			}
//		return responseJson;
//	}
	
	@Override
	public List<ShiroUser> findList(String type, Long typeId) {
		List<ShiroUser> list = (List) entityDao.findByTypeId(type, typeId);
		return list;
	}

	@Override 
	 public PaginationResult<ShiroUser> findAllByPage(Pagination<ShiroUser> pagination){

        SpecificationUtil<ShiroUser> specificationUtil = new SpecificationUtil<ShiroUser>();

        Map<String, Object> searchParams = new HashMap<String, Object>();

        ShiroUser shiroUser = new ShiroUser();
        
        shiroUser =  pagination.dataTable2Entry(shiroUser, pagination);//封装前段调用的数据。
        
        List<String> properties = new ArrayList<String>();
        properties.add("id");
   	    Sort sort = new Sort(Direction.DESC, properties);
   	 
   	    sort= pagination.dataTableOrder(pagination,sort,properties);
       
        String  extra_search = pagination.getExtra_search();//查询条件
        log.info("extra_search="+extra_search);
        
        
		String paramArray[] = extra_search.split("&");
		Map map = new HashMap();
		for(int i =0;i<paramArray.length;i++){
			 String name = paramArray[i].split("=")[0];
			if(paramArray[i].split("=").length==2){
				String value = paramArray[i].split("=")[1];
				map.put(name, value);
			}else{
				 map.put(name, "");
			}
		}

		if(!map.get("username").equals("")){
			 searchParams.put("LIKES_username", map.get("userName"));
		}

		if(!map.get("status").equals("")){
			 searchParams.put("EQS_status", map.get("status"));
			}

		log.info("searchParams.toString()=="+searchParams.toString());

        Specification<ShiroUser> specification = specificationUtil.buildSpecification(searchParams,"and");
   
        int page= pagination.getStart()/pagination.getPageSize();
        PageRequest PageRequest = new PageRequest( page,pagination.getPageSize(), sort);

        Page<ShiroUser> list = entityDao.findAll(specification, PageRequest);

		PaginationResult<ShiroUser> pa=new PaginationResult();
		pa.setData(list.getContent());
		pa.setRecordsFiltered(list.getTotalElements());
		pa.setRecordsTotal(list.getTotalElements());
		pa.setDraw(new Integer(pagination.getDraw()));

        return pa;
		
	  }
	
	@Override
	@Autowired
	public void setEntityDao(ShiroUserDao entityDao) {
		this.entityDao = entityDao;
	}
}
